classdef TestDataTransformer
    % TESTDATATRANSFORMER 测试数据转换器
    % 基于DO-178规则第4条（架构分离原则）设计
    % 负责测试数据在不同格式之间的转换
    %
    % 功能：
    %   - 测试用例数据转换为GUI表格格式
    %   - 测试报告状态格式化
    %   - 覆盖率数据格式化
    %   - 测试结果数据处理
    %
    % 设计原则：
    %   - 纯静态方法，无状态
    %   - 单一职责：只负责数据转换
    %   - 可复用：可被GUI和其他模块调用
    %   - 错误明确：遵循规则第2条
    %
    % 使用示例：
    %   % 转换测试用例数据
    %   tableData = TestDataTransformer.convertTestCasesToTable(testCases);
    %   
    %   % 格式化测试状态
    %   statusText = TestDataTransformer.formatTestStatus('Passed');
    %   
    %   % 格式化覆盖率
    %   coverageText = TestDataTransformer.formatCoverage(85.5);
    %
    % 作者: MBD Platform Team
    % 日期: 2025-10-05
    % 遵循DO-178标准
    
    methods (Static)
        
        %% ==================== 测试用例数据转换 ====================
        
        function tableData = convertTestCasesToTable(testCases)
            % 将测试用例结构体数组转换为GUI表格格式
            % 输入：
            %   testCases - 测试用例结构体数组（来自getModelTestCaseStatus）
            % 输出：
            %   tableData - cell数组，6列：TestID, Description, Type, Status, Requirement, StartTime
            % 基于规则第2条：明确验证和报告错误
            
            % 验证输入
            if nargin < 1 || isempty(testCases)
                tableData = {};
                return;
            end
            
            try
                fprintf('📊 正在转换 %d 个测试用例为表格格式\n', length(testCases));
                
                numCases = length(testCases);
                tableData = cell(numCases, 6);
                
                for i = 1:numCases
                    tableData{i, 1} = TestDataTransformer.getFieldValue(testCases(i), 'TestID', '');
                    tableData{i, 2} = TestDataTransformer.getFieldValue(testCases(i), 'Description', '');
                    tableData{i, 3} = TestDataTransformer.getFieldValue(testCases(i), 'Type', '');
                    tableData{i, 4} = TestDataTransformer.formatTestStatus(...
                        TestDataTransformer.getFieldValue(testCases(i), 'Status', 'Unknown'));
                    tableData{i, 5} = TestDataTransformer.getFieldValue(testCases(i), 'Requirement', '');
                    tableData{i, 6} = TestDataTransformer.formatTimestamp(...
                        TestDataTransformer.getFieldValue(testCases(i), 'StartTime', ''));
                end
                
                fprintf('✅ 测试用例转换完成\n');
                
            catch ME
                error('TestDataTransformer:ConversionFailed', ...
                    '测试用例转换失败: %s', ME.message);
            end
        end
        
        function urls = extractRequirementURLs(testCases)
            % 提取测试用例中的需求URL
            % 输入：
            %   testCases - 测试用例结构体数组
            % 输出：
            %   urls - cell数组，包含需求URL
            
            if nargin < 1 || isempty(testCases)
                urls = {};
                return;
            end
            
            numCases = length(testCases);
            urls = cell(numCases, 1);
            
            for i = 1:numCases
                urls{i} = TestDataTransformer.getFieldValue(testCases(i), 'RequirementURL', '');
            end
        end
        
        %% ==================== 报告状态格式化 ====================
        
        function statusStruct = formatReportStatus(reportStatus)
            % 格式化报告状态为GUI显示格式（灯的颜色）
            % 输入：
            %   reportStatus - 来自TestManagementService.getReportStatus的结构体
            % 输出：
            %   statusStruct - 包含颜色值的结构体
            
            statusStruct = struct();
            
            if isempty(reportStatus)
                % 默认灰色（未知状态）
                statusStruct.hlrTestLampColor = [0.5 0.5 0.5];
                statusStruct.hlrCoverageLampColor = [0.5 0.5 0.5];
                statusStruct.llrTestLampColor = [0.5 0.5 0.5];
                statusStruct.llrCoverageLampColor = [0.5 0.5 0.5];
                return;
            end
            
            % HLR测试报告：绿色（存在）或灰色（不存在）
            if reportStatus.hlrTestReportExists
                statusStruct.hlrTestLampColor = [0 1 0];
            else
                statusStruct.hlrTestLampColor = [0.5 0.5 0.5];
            end
            
            % HLR覆盖率报告：绿色（存在）或灰色（不存在）
            if reportStatus.hlrCoverageReportExists
                statusStruct.hlrCoverageLampColor = [0 1 0];
            else
                statusStruct.hlrCoverageLampColor = [0.5 0.5 0.5];
            end
            
            % LLR测试报告：绿色（存在）或灰色（不存在）
            if reportStatus.llrTestReportExists
                statusStruct.llrTestLampColor = [0 1 0];
            else
                statusStruct.llrTestLampColor = [0.5 0.5 0.5];
            end
            
            % LLR覆盖率报告：绿色（存在）或灰色（不存在）
            if reportStatus.llrCoverageReportExists
                statusStruct.llrCoverageLampColor = [0 1 0];
            else
                statusStruct.llrCoverageLampColor = [0.5 0.5 0.5];
            end
        end
        
        %% ==================== 测试状态格式化 ====================
        
        function formattedStatus = formatTestStatus(status)
            % 格式化测试状态为显示文本
            % 输入：
            %   status - 测试状态字符串
            % 输出：
            %   formattedStatus - 格式化后的状态字符串
            
            if isempty(status)
                formattedStatus = '未知';
                return;
            end
            
            switch lower(status)
                case {'passed', 'pass', 'success'}
                    formattedStatus = '✅ 通过';
                case {'failed', 'fail', 'failure'}
                    formattedStatus = '❌ 失败';
                case {'running', 'in_progress'}
                    formattedStatus = '🔄 运行中';
                case {'pending', 'queued'}
                    formattedStatus = '⏳ 待运行';
                case {'skipped', 'skip'}
                    formattedStatus = '⏭️ 跳过';
                case {'error'}
                    formattedStatus = '⚠️ 错误';
                otherwise
                    formattedStatus = status;
            end
        end
        
        %% ==================== 覆盖率格式化 ====================
        
        function formattedCoverage = formatCoverage(coveragePercent)
            % 格式化覆盖率百分比为显示文本
            % 输入：
            %   coveragePercent - 覆盖率百分比（0-100）
            % 输出：
            %   formattedCoverage - 格式化后的覆盖率字符串
            
            if isempty(coveragePercent) || ~isnumeric(coveragePercent)
                formattedCoverage = '未知';
                return;
            end
            
            % 格式化为百分比，保留1位小数
            formattedCoverage = sprintf('%.1f%%', coveragePercent);
            
            % 根据覆盖率添加emoji指示器
            if coveragePercent >= 90
                formattedCoverage = ['✅ ' formattedCoverage];
            elseif coveragePercent >= 70
                formattedCoverage = ['⚠️ ' formattedCoverage];
            else
                formattedCoverage = ['❌ ' formattedCoverage];
            end
        end
        
        %% ==================== 测试模式格式化 ====================
        
        function formattedMode = formatTestMode(testMode)
            % 格式化测试模式为显示文本
            % 输入：
            %   testMode - 测试模式：'MIL', 'SIL', 'PIL'
            % 输出：
            %   formattedMode - 格式化后的测试模式字符串
            
            if isempty(testMode)
                formattedMode = '未指定';
                return;
            end
            
            switch upper(testMode)
                case 'MIL'
                    formattedMode = 'MIL（模型在环）';
                case 'SIL'
                    formattedMode = 'SIL（软件在环）';
                case 'PIL'
                    formattedMode = 'PIL（处理器在环）';
                otherwise
                    formattedMode = testMode;
            end
        end
        
        %% ==================== 测试类型格式化 ====================
        
        function formattedType = formatTestType(testType)
            % 格式化测试类型为显示文本
            % 输入：
            %   testType - 测试类型：'HLR', 'LLR'
            % 输出：
            %   formattedType - 格式化后的测试类型字符串
            
            if isempty(testType)
                formattedType = '未指定';
                return;
            end
            
            switch upper(testType)
                case 'HLR'
                    formattedType = 'HLR（高级需求）';
                case 'LLR'
                    formattedType = 'LLR（低级需求）';
                otherwise
                    formattedType = testType;
            end
        end
        
        %% ==================== 时间戳格式化 ====================
        
        function formattedTime = formatTimestamp(timestamp)
            % 格式化时间戳为可读字符串
            % 输入：
            %   timestamp - 时间戳（字符串或datetime或数值）
            % 输出：
            %   formattedTime - 格式化后的时间字符串
            
            if isempty(timestamp)
                formattedTime = '-';
                return;
            end
            
            try
                if ischar(timestamp) || isstring(timestamp)
                    % 如果已经是字符串，直接返回
                    formattedTime = char(timestamp);
                elseif isdatetime(timestamp)
                    % 如果是datetime，格式化为字符串
                    formattedTime = datestr(timestamp, 'yyyy-mm-dd HH:MM:SS');
                elseif isnumeric(timestamp)
                    % 如果是数值（datenum），转换为字符串
                    formattedTime = datestr(timestamp, 'yyyy-mm-dd HH:MM:SS');
                else
                    formattedTime = '-';
                end
            catch
                formattedTime = '-';
            end
        end
        
        %% ==================== 测试结果摘要 ====================
        
        function summary = generateTestSummary(testCases)
            % 生成测试用例统计摘要
            % 输入：
            %   testCases - 测试用例结构体数组
            % 输出：
            %   summary - 包含统计信息的结构体
            
            summary = struct(...
                'totalCount', 0, ...
                'passedCount', 0, ...
                'failedCount', 0, ...
                'skippedCount', 0, ...
                'pendingCount', 0, ...
                'passRate', 0);
            
            if isempty(testCases)
                return;
            end
            
            summary.totalCount = length(testCases);
            
            % 统计各状态的数量
            for i = 1:length(testCases)
                status = lower(TestDataTransformer.getFieldValue(testCases(i), 'Status', ''));
                
                if ismember(status, {'passed', 'pass', 'success'})
                    summary.passedCount = summary.passedCount + 1;
                elseif ismember(status, {'failed', 'fail', 'failure', 'error'})
                    summary.failedCount = summary.failedCount + 1;
                elseif ismember(status, {'skipped', 'skip'})
                    summary.skippedCount = summary.skippedCount + 1;
                elseif ismember(status, {'pending', 'queued', 'in_progress', 'running'})
                    summary.pendingCount = summary.pendingCount + 1;
                end
            end
            
            % 计算通过率
            if summary.totalCount > 0
                summary.passRate = (summary.passedCount / summary.totalCount) * 100;
            end
        end
        
        function summaryText = formatTestSummary(summary)
            % 格式化测试摘要为显示文本
            % 输入：
            %   summary - 来自generateTestSummary的摘要结构体
            % 输出：
            %   summaryText - 格式化后的摘要文本
            
            if isempty(summary) || summary.totalCount == 0
                summaryText = '无测试用例';
                return;
            end
            
            summaryText = sprintf(...
                '📊 测试摘要：共 %d 个用例 | ✅通过 %d | ❌失败 %d | ⏭️跳过 %d | ⏳待运行 %d | 通过率 %.1f%%', ...
                summary.totalCount, ...
                summary.passedCount, ...
                summary.failedCount, ...
                summary.skippedCount, ...
                summary.pendingCount, ...
                summary.passRate);
        end
        
        %% ==================== 辅助方法 ====================
        
        function value = getFieldValue(structData, fieldName, defaultValue)
            % 安全地获取结构体字段值
            % 输入：
            %   structData - 结构体
            %   fieldName - 字段名称
            %   defaultValue - 默认值（如果字段不存在）
            % 输出：
            %   value - 字段值或默认值
            
            if isfield(structData, fieldName)
                value = structData.(fieldName);
                if isempty(value)
                    value = defaultValue;
                end
            else
                value = defaultValue;
            end
        end
        
        %% ==================== 数据验证 ====================
        
        function isValid = validateTestCaseData(testCases)
            % 验证测试用例数据结构的完整性
            % 输入：
            %   testCases - 测试用例结构体数组
            % 输出：
            %   isValid - 布尔值，表示数据是否有效
            
            isValid = false;
            
            if isempty(testCases)
                fprintf('⚠️ 测试用例数据为空\n');
                return;
            end
            
            % 检查是否为结构体数组
            if ~isstruct(testCases)
                fprintf('❌ 测试用例数据必须是结构体数组\n');
                return;
            end
            
            % 检查必需字段
            requiredFields = {'TestID', 'Description', 'Type', 'Status'};
            for i = 1:length(requiredFields)
                if ~isfield(testCases, requiredFields{i})
                    fprintf('❌ 缺少必需字段: %s\n', requiredFields{i});
                    return;
                end
            end
            
            isValid = true;
            fprintf('✅ 测试用例数据验证通过\n');
        end
    end
end




